﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace DaveSexton.Labs
{
	[TemplatePart(Name = "PART_Start", Type = typeof(ButtonBase))]
	[TemplatePart(Name = "PART_Input", Type = typeof(TextBox))]
	public abstract partial class WindowsConsoleLab : WindowsLab, IGUIConsoleLab
	{
		#region Public Properties
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "It's immutable.")]
		public static readonly DependencyProperty IsRunningProperty = DependencyProperty.Register("IsRunning", typeof(bool), typeof(WindowsConsoleLab), new PropertyMetadata(false));
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "It's immutable.")]
		public static readonly DependencyProperty WaitingForUserInputProperty = DependencyProperty.Register("WaitingForUserInput", typeof(bool), typeof(WindowsConsoleLab), new PropertyMetadata(false));
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "It's immutable.")]
		public static readonly DependencyProperty HasExperimentsProperty = DependencyProperty.Register("HasExperiments", typeof(bool), typeof(WindowsConsoleLab), new PropertyMetadata(false));
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "It's immutable.")]
		public static readonly DependencyPropertyKey ExperimentsProperty = DependencyProperty.RegisterReadOnly("Experiments", typeof(IList<IExperiment>), typeof(WindowsConsoleLab), new PropertyMetadata(null));
		public static readonly DependencyProperty SelectedExperimentProperty = DependencyProperty.Register("SelectedExperiment", typeof(IExperiment), typeof(WindowsConsoleLab), new PropertyMetadata(null, SelectedExperiment_Changed));
		public static readonly DependencyProperty PauseBetweenExperimentsProperty = DependencyProperty.Register("PauseBetweenExperiments", typeof(bool), typeof(WindowsConsoleLab), new PropertyMetadata(true));
		#endregion

		#region Private / Protected
		private ButtonBase startButton;
		private TextBox inputTextBox;
		#endregion

		#region Constructors
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline",
			Justification = "All static fields are being initialized inline.  The static constructor is for overriding metadata only.")]
		static WindowsConsoleLab()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowsConsoleLab), new FrameworkPropertyMetadata(typeof(WindowsConsoleLab)));
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="WindowsConsoleLab" /> class for derived classes.
		/// </summary>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
			Justification = "Invariants are excluded in Release builds.")]
		protected WindowsConsoleLab()
			: base(traceHeader: false)
		{
			Contract.Ensures(!HasProxy);

			Unloaded += Lab_Unloaded;
		}
		#endregion

		#region Methods
		#endregion

		#region Event Handlers
		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();

			startButton = (ButtonBase) GetTemplateChild("PART_Start");
			inputTextBox = (TextBox) GetTemplateChild("PART_Input");

			if (startButton != null)
			{
				startButton.Click += StartButton_Click;
			}

			if (inputTextBox != null)
			{
				inputTextBox.KeyUp += InputTextBox_KeyUp;
				inputTextBox.AddHandler(TextBoxBase.TextInputEvent, new TextCompositionEventHandler(InputTextBox_TextInput), handledEventsToo: true);
			}
		}
		#endregion
	}
}